// ==UserScript==
// @name         TMVN Club Finance CN
// @namespace    https://trophymanager.com
// @version      1.2024060801
// @author       Xpand 修复：提瓦特元素反应(ID:4731723),汉化：太原龙城(ID:246770)
// @description  Trophymanager: TrophyManager: 使用这个脚本来估算这个赛季的财政预算。它帮助我回答这样的问题: 我可以用多少钱买明星球员？应维持多少工资？需要买卖多少球员才能负担得起建设设施？它不能完全准确，但足以给俱乐部的财务状况一个大致的看法。
// @match      https://trophymanager.com/club/*
// @match      https://trophymanager.com/club/*/
// @exclude      https://trophymanager.com/club/*/squad/
// @grant        none
// @downloadURL https://gitee.com/trophymanagerCN/tmjs/raw/master/493678/TMVN%20Club%20Finance%20CN.user.js
// @updateURL https://gitee.com/trophymanagerCN/tmjs/raw/master/493678/TMVN%20Club%20Finance%20CN.meta.js
// ==/UserScript==

(function () {
    'use strict';

    const NOTE = "如果有杯赛、国际比赛，或者经常对阵大俱乐部，推荐球场容量应该更大一些。";

    const COLOR = {
        DEFAULT: "color:White;",
        SPECTATOR: "color:Orange;",
        COMMERCE: "color:Aqua;",
        SEAT: "color:Yellow;",
        INJURY: "color:GreenYellow;",
        YATG: "color:Yellow;",
        IN: "color:Blue;",
        OUT: "color:Black;",
        FINAL: "color:Darkred;",
        NOTE: "color:Darkgray"
    }

    const COMMERCE_PRICE = {
        FAST_FOOD_PLACE: 4,
        MERCHANDISE_STAND: 10,
        MERCHANDISE_STORE: 20,
        RESTAURANT: 5,
        SAUSAGE_STAND: 2.5
    }

    const COMMERCE_INCOME_FACTOR = {
        FAST_FOOD_PLACE: 17,
        MERCHANDISE_STAND: 17,
        MERCHANDISE_STORE: 12,
        RESTAURANT: 17,
        SAUSAGE_STAND: 17
    }

    const CALCULATE_EXTRA_MATCH = {
        FAST_FOOD_PLACE: 1,
        MERCHANDISE_STAND: 1,
        MERCHANDISE_STORE: 0,
        RESTAURANT: 1,
        SAUSAGE_STAND: 1
    }

    const COMMERCE_MAINTAIN = {
        FAST_FOOD_PLACE: 45000,
        MERCHANDISE_STAND: 112500,
        RESTAURANT: 56250,
        SAUSAGE_STAND: 28125
    }

    const TICKET_PRICE = 200;
    const SEAT_MAINTAIN = 35;

    const MERCHANDISE_STORE_MAINTAIN = [0, 50000, 150000, 250000, 350000, 450000, 550000, 650000, 750000, 850000, 950000];
    const PARKING_MAINTAIN = [0, 10000, 50000, 100000, 150000, 250000, 375000, 500000, 625000, 800000, 1000000];
    const TOILETS_MAINTAIN = [0, 10000, 50000, 100000, 150000, 250000, 375000, 500000, 625000, 800000, 1000000];
    const PHYSIO_MAINTAIN = [0, 10000, 50000, 100000, 150000, 250000, 375000, 500000, 625000, 800000, 1000000];

    const TRAINING_GROUNDS_MAINTAIN = [0, 30000, 185000, 612500, 1250000, 2150000, 3650000, 5350000, 7650000, 10250000, 13500000];
    const YOUTH_ACADEMY_MAINTAIN = [0, 25000, 150000, 500000, 1000000, 1750000, 3000000, 4350000, 6250000, 8350000, 11000000];
    const MEDICAL_CENTER_MAINTAIN = [0, 50000, 250000, 625000, 1250000, 2000000, 3000000, 4500000, 6000000, 8000000, 10000000];

    const FLOODLIGHTS_MAINTAIN = [0, 100000, 500000];
    const PITCH_DRAINING_MAINTAIN = [0, 50000];
    const PITCH_COVER_MAINTAIN = [0, 50000];
    const SPRINKLERS_MAINTAIN = [0, 50000];
    const HEATING_MAINTAIN = [0, 350000];

    const TV_MONEY = [0, 11000000, 10000000, 9500000, 9000000, 8500000, 8000000];
    const SPONSORS = [0, 25000000, 22500000, 20000000, 17500000, 15000000, 12500000];

    var physioLevel,
        pitchDrainingLevel,
        pitchCoverLevel,
        sprinklersLevel,
        heatingLevel,
        floodlightsLevel,
        parkingLevel,
        toiletsLevel,
        restaurantLevel,
        merchandiseStandLevel,
        fastFoodPlaceLevel,
        sausageStandLevel,
        merchandiseStoreLevel,
        medicalCenterLevel,
        youthAcademyLevel,
        trainingGroundsLevel;

    var estimateAttendance,
        averageAttendance,
        currentCapacity,
        recommendCapacity,
        ticketIncome,
        seatMantain,
        ticketProfit,
        commerceIncome,
        commerceMaintain,
        commerceProfit,
        tvMoney,
        sponsors,
        otherMaintain,
        totalProfit;

    var extraHomeMatch,
        tradePlayer,
        buyStar,
        playerWage,
        staffWage,
        building,
        adjust;
    extraHomeMatch = tradePlayer = buyStar = playerWage = staffWage = building = adjust = 0;

    var myClubId,
        clubId,
        division,
        fanBase = -1;
    var getHomeIdInterval = setInterval(getHomeId, 500);
    var mainInterval = setInterval(main, 500);

    /**
     * 获取home ID。
     * 该函数首先检查变量myClubId是否已定义，如果已定义，则清除定时器getHomeIdInterval。
     * 如果myClubId未定义，尝试从页面元素中获取俱乐部ID，并赋值给myClubId。
     *
     * @returns {void} 该函数没有返回值。
     */
    function getHomeId() {
        // 检查myClubId是否已定义，若已定义则清除定时器
        if (myClubId != undefined) {
            clearInterval(getHomeIdInterval);
        } else {
            // 尝试捕获异常，从页面中获取俱乐部ID
            try {
                myClubId = $('.club.faux_link').attr('club');
            } catch (e) {
            }
        }
    }

    /**
     * 主函数，用于获取并处理与足球俱乐部相关的信息。
     * 无参数。
     * 无显式返回值，但可能在执行过程中修改全局变量或执行其他副作用。
     */
    function main() {
        // 检查是否有设置的myClubId，若无则不执行后续逻辑
        if (myClubId != '') {
            // 清除可能存在的定时器
            clearInterval(mainInterval);
            // 从当前页面URL中提取clubId
            clubId = $('a.selected.none').attr('href').split('/')[2];
            // 获取页面中指定元素的division属性值
            division = $('.box_sub_header.align_center a')[$('.box_sub_header.align_center a').length - 1].getAttribute('division');
            // 从页面元素中提取俱乐部信息，并查找球迷基数
            var clubInfoArr = $('#club_info div')[0].innerText.split('\n');
            for (var i = clubInfoArr.length - 1; i >= 0; i--) {
                if (clubInfoArr[i].trim().startsWith('球迷协会： ')) {
                    fanBase = clubInfoArr[i].trim().split(' ')[1].replace(/,/g, ''); // 移除逗号并转换为数字
                    // 检查fanBase是否为数字，若不是则设为0
                    if (isNaN(fanBase)) {
                        fanBase = 0; // 在实时比赛时间时，可能无法获取准确的球迷基数
                    } else {
                        fanBase = Number(fanBase);
                    }
                    break;
                }
            }
            console.log(clubInfoArr);
            // 若fanBase为-1，则表示这是B队，不进行后续操作
            if (fanBase == -1) {
                return;
            }
            console.log("check");
            // 检查是否自己的俱乐部，是则获取薪资信息
            if (myClubId == clubId) {
                let playerWeekWage = -1, // 球员周薪
                    staffWeekWage = -1; // 工作人员周薪
                // 设置jQuery ajax请求为同步
                $.ajaxSetup({
                    async: false
                });

                // 请求球员薪资信息
                $.ajax('https://trophymanager.com/finances/wages/', {
                    type: "GET",
                    dataType: 'html',
                    crossDomain: true,
                    success: function (response) {
                        try {
                            // 提取并处理最后一名球员的周薪信息
                            let playerWageTr = $('#tab0 tr', response)[$('#tab0 tr', response).length - 1];
                            playerWeekWage = Number($('td', playerWageTr)[1].innerText.replace(/,/g, ''));
                        } catch (e) {
                        }

                        try {
                            // 提取并处理最后一名工作人员的周薪信息
                            let staffWageTr = $('#tab1 tr', response)[$('#tab1 tr', response).length - 1];
                            staffWeekWage = Number($('td', staffWageTr)[2].innerText.replace(/,/g, ''));
                        } catch (e) {
                        }
                    },
                    error: function (e) {
                    }
                });

                // 恢复jQuery ajax请求为异步
                $.ajaxSetup({
                    async: true
                });
                // 更新全局变量
                if (playerWeekWage != -1) {
                    playerWage = playerWeekWage;
                }
                if (staffWeekWage != -1) {
                    staffWage = staffWeekWage;
                }
            }

            // 准备数据并呈现
            parepareData();
            presentation();
        }
    }

    function parepareData() {
        $.ajaxSetup({
            async: false
        });

        $.ajax('https://trophymanager.com/stadium/' + clubId, {
            type: "GET",
            dataType: 'html',
            crossDomain: true,
            success: function (response) {
                let facility = $('map[name="facility_map"]', response)[0];

                let stadium = facility.children[0];

                let floodlights = facility.children[2];
                let parking = facility.children[6];
                let toilets = facility.children[9];

                let restaurant = facility.children[7];
                let merchandiseStand = facility.children[4];
                let fastFoodPlace = facility.children[1];
                let sausageStand = facility.children[8];
                let merchandiseStore = facility.children[5];

                let medicalCenter = facility.children[3];

                let youthAcademy = facility.children[11];
                let trainingGrounds = facility.children[10];

                let stadiumElementArr = $('p', new DOMParser().parseFromString(stadium.getAttribute('tooltip'), 'text/html'));

                currentCapacity = Number(stadiumElementArr[1].innerText.split(' ')[1].replace(/,/g, ''));

                let physioText = stadiumElementArr[2].innerText.trim();
                if (physioText == '理疗师 ') {
                    physioLevel = 0;
                } else {
                    physioLevel = Number(physioText.substr(5, physioText.length - 5 - 1)); //'Physio [' = 8 || '理疗师 [' = 5
                }

                $('img', stadiumElementArr[4])[0].src.endsWith("small_red_x.png") ? pitchDrainingLevel = 0 : pitchDrainingLevel = 1;
                $('img', stadiumElementArr[5])[0].src.endsWith("small_red_x.png") ? pitchCoverLevel = 0 : pitchCoverLevel = 1;
                $('img', stadiumElementArr[6])[0].src.endsWith("small_red_x.png") ? sprinklersLevel = 0 : sprinklersLevel = 1;
                $('img', stadiumElementArr[7])[0].src.endsWith("small_red_x.png") ? heatingLevel = 0 : heatingLevel = 1;

                floodlightsLevel = identifyFacilityLevel(floodlights);
                parkingLevel = identifyFacilityLevel(parking);
                toiletsLevel = identifyFacilityLevel(toilets);

                restaurantLevel = identifyFacilityLevel(restaurant);
                merchandiseStandLevel = identifyFacilityLevel(merchandiseStand);
                fastFoodPlaceLevel = identifyFacilityLevel(fastFoodPlace);
                sausageStandLevel = identifyFacilityLevel(sausageStand);
                merchandiseStoreLevel = identifyFacilityLevel(merchandiseStore);

                medicalCenterLevel = identifyFacilityLevel(medicalCenter);

                youthAcademyLevel = identifyFacilityLevel(youthAcademy);
                trainingGroundsLevel = identifyFacilityLevel(trainingGrounds);

                averageAttendance = calculateAverageAttendance(parkingLevel, toiletsLevel, floodlightsLevel, fanBase, currentCapacity);
                estimateAttendance = calculateEstimateAttendance(parkingLevel, toiletsLevel, floodlightsLevel, fanBase, currentCapacity);
                recommendCapacity = calculateRecommendCapacity(parkingLevel, toiletsLevel, floodlightsLevel, fanBase);

                ticketIncome = calculateTicketIncome(extraHomeMatch, averageAttendance);
                seatMantain = calculateSeatMaintain(currentCapacity);
                ticketProfit = ticketIncome - seatMantain;

                commerceIncome = calculateCommerceIncome(extraHomeMatch, averageAttendance, restaurantLevel, merchandiseStandLevel, fastFoodPlaceLevel, sausageStandLevel, merchandiseStoreLevel);
                commerceMaintain = calculateCommerceMaintain(restaurantLevel, merchandiseStandLevel, fastFoodPlaceLevel, sausageStandLevel, merchandiseStoreLevel);
                commerceProfit = commerceIncome - commerceMaintain;

                tvMoney = calculateTVMoney(division);
                sponsors = calculateSponsors(division);
                otherMaintain = calculateOtherMaintain(physioLevel, pitchDrainingLevel, pitchCoverLevel, sprinklersLevel, heatingLevel, floodlightsLevel, parkingLevel, toiletsLevel, medicalCenterLevel, youthAcademyLevel, trainingGroundsLevel);

                try {
                    if (playerWage == 0) { //not home club
                        playerWage = JSON.parse(localStorage.getItem(clubId + "_SQUAD_VALUE")).Wage; //TMVN Squad Value script
                    }
                } catch (e) {
                }

                totalProfit = ticketProfit + commerceProfit + tvMoney + sponsors + tradePlayer - otherMaintain - playerWage * 12 - staffWage * 12 - building - buyStar + adjust;

            },
            error: function (e) {
            }
        });

        $.ajaxSetup({
            async: true
        });
    }

    function presentation() {
        let stadiumArea =
            '<div class="box">' +
            '<div class="box_head"><h2 class="std">财政预算</h2></div>' +
            '<div class="box_body">' +
            '<div class="box_shadow"></div>' +
            '<div id="tm_script_club_stadium_area_id" class="content_menu"></div>' +
            '<div class="box_footer"><div></div></div>' +
            '</div>';

        $(".column1").append(stadiumArea);

        let stadiumArea_content = "<table>";
        stadiumArea_content += '<tr><td style=' + COLOR.DEFAULT + '>球迷数量: </td><td style="text-align: right"><span style="display: inline-block;"><input id="tm_script_input_fanbase" type="text" class="embossed" style="width: 50px; min-width: 50px; line-height: 100%; padding: 3px 3px 4px 3px; text-align: right;"></span></td></tr>';
        stadiumArea_content += '<tr><td style=' + COLOR.SPECTATOR + '>球场容量: </td><td style="text-align: right"><span style="display: inline-block;"><input id="tm_script_input_current_capacity" type="text" class="embossed" style="width: 50px; min-width: 50px; line-height: 100%; padding: 3px 3px 4px 3px; text-align: right;"></span></td></tr>';

        stadiumArea_content += '<tr><td style=' + COLOR.SPECTATOR + '>灯光: </td><td style="text-align: right"><span style="display: inline-block;"><input id="tm_script_input_floodlights" type="text" class="embossed" style="width: 50px; min-width: 50px; line-height: 100%; padding: 3px 3px 4px 3px; text-align: right;"></span></td></tr>';
        stadiumArea_content += '<tr><td style=' + COLOR.SPECTATOR + '>停车场: </td><td style="text-align: right"><span style="display: inline-block;"><input id="tm_script_input_parking" type="text" class="embossed" style="width: 50px; min-width: 50px; line-height: 100%; padding: 3px 3px 4px 3px; text-align: right;"></span></td></tr>';
        stadiumArea_content += '<tr><td style=' + COLOR.SPECTATOR + '>厕所: </td><td style="text-align: right"><span style="display: inline-block;"><input id="tm_script_input_toilets" type="text" class="embossed" style="width: 50px; min-width: 50px; line-height: 100%; padding: 3px 3px 4px 3px; text-align: right;"></span></td></tr>';

        stadiumArea_content += '<tr><td style=' + COLOR.INJURY + '>理疗师: </td><td style="text-align: right"><span style="display: inline-block;"><input id="tm_script_input_physio" type="text" class="embossed" style="width: 50px; min-width: 50px; line-height: 100%; padding: 3px 3px 4px 3px; text-align: right;"></span></td></tr>';
        stadiumArea_content += '<tr><td style=' + COLOR.INJURY + '>排水系统: </td><td style="text-align: right"><span style="display: inline-block;"><input id="tm_script_input_pitch_draining" type="text" class="embossed" style="width: 50px; min-width: 50px; line-height: 100%; padding: 3px 3px 4px 3px; text-align: right;"></span></td></tr>';
        stadiumArea_content += '<tr><td style=' + COLOR.INJURY + '>草皮覆盖: </td><td style="text-align: right"><span style="display: inline-block;"><input id="tm_script_input_pitch_cover" type="text" class="embossed" style="width: 50px; min-width: 50px; line-height: 100%; padding: 3px 3px 4px 3px; text-align: right;"></span></td></tr>';
        stadiumArea_content += '<tr><td style=' + COLOR.INJURY + '>喷淋系统: </td><td style="text-align: right"><span style="display: inline-block;"><input id="tm_script_input_sprinklers" type="text" class="embossed" style="width: 50px; min-width: 50px; line-height: 100%; padding: 3px 3px 4px 3px; text-align: right;"></span></td></tr>';
        stadiumArea_content += '<tr><td style=' + COLOR.INJURY + '>地热系统: </td><td style="text-align: right"><span style="display: inline-block;"><input id="tm_script_input_heating" type="text" class="embossed" style="width: 50px; min-width: 50px; line-height: 100%; padding: 3px 3px 4px 3px; text-align: right;"></span></td></tr>';
        stadiumArea_content += '<tr><td style=' + COLOR.INJURY + '>医疗中心: </td><td style="text-align: right"><span style="display: inline-block;"><input id="tm_script_input_medical_center" type="text" class="embossed" style="width: 50px; min-width: 50px; line-height: 100%; padding: 3px 3px 4px 3px; text-align: right;"></span></td></tr>';

        stadiumArea_content += '<tr><td style=' + COLOR.COMMERCE + '>餐厅: </td><td style="text-align: right"><span style="display: inline-block;"><input id="tm_script_input_restaurant" type="text" class="embossed" style="width: 50px; min-width: 50px; line-height: 100%; padding: 3px 3px 4px 3px; text-align: right;"></span></td></tr>';
        stadiumArea_content += '<tr><td style=' + COLOR.COMMERCE + '>纪念品摊: </td><td style="text-align: right"><span style="display: inline-block;"><input id="tm_script_input_merchandise_stand" type="text" class="embossed" style="width: 50px; min-width: 50px; line-height: 100%; padding: 3px 3px 4px 3px; text-align: right;"></span></td></tr>';
        stadiumArea_content += '<tr><td style=' + COLOR.COMMERCE + '>快餐店: </td><td style="text-align: right"><span style="display: inline-block;"><input id="tm_script_input_fast_food_place" type="text" class="embossed" style="width: 50px; min-width: 50px; line-height: 100%; padding: 3px 3px 4px 3px; text-align: right;"></span></td></tr>';
        stadiumArea_content += '<tr><td style=' + COLOR.COMMERCE + '>热狗摊: </td><td style="text-align: right"><span style="display: inline-block;"><input id="tm_script_input_sausage_stand" type="text" class="embossed" style="width: 50px; min-width: 50px; line-height: 100%; padding: 3px 3px 4px 3px; text-align: right;"></span></td></tr>';
        stadiumArea_content += '<tr><td style=' + COLOR.COMMERCE + '>纪念品商店: </td><td style="text-align: right"><span style="display: inline-block;"><input id="tm_script_input_merchandise_store" type="text" class="embossed" style="width: 50px; min-width: 50px; line-height: 100%; padding: 3px 3px 4px 3px; text-align: right;"></span></td></tr>';

        stadiumArea_content += '<tr><td style=' + COLOR.YATG + '>青训学校: </td><td style="text-align: right"><span style="display: inline-block;"><input id="tm_script_input_youth_academy" type="text" class="embossed" style="width: 50px; min-width: 50px; line-height: 100%; padding: 3px 3px 4px 3px; text-align: right;"></span></td></tr>';
        stadiumArea_content += '<tr><td style=' + COLOR.YATG + '>训练基地: </td><td style="text-align: right"><span style="display: inline-block;"><input id="tm_script_input_training_grounds" type="text" class="embossed" style="width: 50px; min-width: 50px; line-height: 100%; padding: 3px 3px 4px 3px; text-align: right;"></span></td></tr>';

        stadiumArea_content += '<tr><td style=' + COLOR.IN + '>额外的主场比赛: </td><td style="text-align: right"><span style="display: inline-block;"><input id="tm_script_input_extra_home_match" type="text" class="embossed" style="width: 50px; min-width: 50px; line-height: 100%; padding: 3px 3px 4px 3px; text-align: right;"></span></td></tr>';
        stadiumArea_content += '<tr><td style=' + COLOR.IN + '>级别: </td><td style="text-align: right"><span style="display: inline-block;"><input id="tm_script_input_division" type="text" class="embossed" style="width: 50px; min-width: 50px; line-height: 100%; padding: 3px 3px 4px 3px; text-align: right;"></span></td></tr>';
        stadiumArea_content += "</table>";

        stadiumArea_content += "<table>";
        stadiumArea_content += '<tr><td style=' + COLOR.IN + '>转会收支: </td><td style="text-align: right"><span style="display: inline-block;"><input id="tm_script_input_trade_player" type="text" class="embossed" style="width: 80px; min-width: 50px; line-height: 100%; padding: 3px 3px 4px 3px; text-align: right;"></span></td></tr>';
        stadiumArea_content += '<tr><td style=' + COLOR.OUT + '>引援预算: </td><td style="text-align: right"><span style="display: inline-block;"><input id="tm_script_input_buy_star" type="text" class="embossed" style="width: 80px; min-width: 50px; line-height: 100%; padding: 3px 3px 4px 3px; text-align: right;"></span></td></tr>';
        stadiumArea_content += '<tr><td style=' + COLOR.OUT + '>球员周薪: </td><td style="text-align: right"><span style="display: inline-block;"><input id="tm_script_input_player_wage" type="text" class="embossed" style="width: 80px; min-width: 50px; line-height: 100%; padding: 3px 3px 4px 3px; text-align: right;"></span></td></tr>';
        stadiumArea_content += '<tr><td style=' + COLOR.OUT + '>职员周薪: </td><td style="text-align: right"><span style="display: inline-block;"><input id="tm_script_input_staff_wage" type="text" class="embossed" style="width: 80px; min-width: 50px; line-height: 100%; padding: 3px 3px 4px 3px; text-align: right;"></span></td></tr>';
        stadiumArea_content += '<tr><td style=' + COLOR.OUT + '>工程花费: </td><td style="text-align: right"><span style="display: inline-block;"><input id="tm_script_input_building" type="text" class="embossed" style="width: 80px; min-width: 50px; line-height: 100%; padding: 3px 3px 4px 3px; text-align: right;"></span></td></tr>';
        stadiumArea_content += '<tr><td style=' + COLOR.DEFAULT + '>其他调节项: </td><td style="text-align: right"><span style="display: inline-block;"><input id="tm_script_input_adjust" type="text" class="embossed" style="width: 80px; min-width: 50px; line-height: 100%; padding: 3px 3px 4px 3px; text-align: right;"></span></td></tr>';

        stadiumArea_content += '<tr><td colspan="2" style="text-align: center;"><span id="tm_script_button_calculate" class="button" style="margin-left: 3px;"><span class="button_border">计算</span></span></td></tr>';
        stadiumArea_content += "</table>";

        stadiumArea_content += "<table>";
        stadiumArea_content += '<tr><td><table><tr style=' + COLOR.SEAT + '><td>平均上座:</td><td style="text-align: right;"><span id="tm_script_span_average_attendance"></span></td></tr></table></td></tr>';
        stadiumArea_content += '<tr><td><table><tr style=' + COLOR.SEAT + '><td>推荐球场容量:</td><td style="text-align: right;"><span id="tm_script_span_recommend_capacity"></span></td></tr></table></td></tr>';

        stadiumArea_content += '<tr><td><table><tr style=' + COLOR.SPECTATOR + '><td>球票收入:</td><td style="text-align: right;"><span id="tm_script_span_ticket_income"></span></td></tr></table></td></tr>';
        stadiumArea_content += '<tr><td><table><tr style=' + COLOR.SPECTATOR + '><td>座位维护:</td><td style="text-align: right;"><span id="tm_script_span_seat_maintain"></span></td></tr></table></td></tr>';
        stadiumArea_content += '<tr><td><table><tr style=' + COLOR.SPECTATOR + '><td>球票利润:</td><td style="text-align: right;"><span id="tm_script_span_ticket_profit"></span></td></tr></table></td></tr>';

        stadiumArea_content += '<tr><td><table><tr style=' + COLOR.COMMERCE + '><td>商业收入:</td><td style="text-align: right;"><span id="tm_script_span_commerce_income"></span></td></tr></table></td></tr>';
        stadiumArea_content += '<tr><td><table><tr style=' + COLOR.COMMERCE + '><td>商业维护:</td><td style="text-align: right;"><span id="tm_script_span_commerce_maintain"></span></td></tr></table></td></tr>';
        stadiumArea_content += '<tr><td><table><tr style=' + COLOR.COMMERCE + '><td>商业利润:</td><td style="text-align: right;"><span id="tm_script_span_commerce_profit"></span></td></tr></table></td></tr>';

        stadiumArea_content += '<tr><td><table><tr style=' + COLOR.IN + '><td>转播收入:</td><td style="text-align: right;"><span id="tm_script_span_tv_money"></span></td></tr></table></td></tr>';
        stadiumArea_content += '<tr><td><table><tr style=' + COLOR.IN + '><td>赞助收入:</td><td style="text-align: right;"><span id="tm_script_span_sponsors"></span></td></tr></table></td></tr>';
        stadiumArea_content += '<tr><td><table><tr style=' + COLOR.OUT + '><td>非盈利维护:</td><td style="text-align: right;"><span id="tm_script_span_other_maintain"></span></td></tr></table></td></tr>';
        stadiumArea_content += '<tr><td><table><tr style=' + COLOR.FINAL + '><td>总收支:</td><td style="text-align: right;"><span id="tm_script_span_total_profit"></span></td></tr></table></td></tr>';
        stadiumArea_content += '<tr><td style="color:Darkgray; font-size:smaller; font-style:italic">' + NOTE + '</td></tr>';
        stadiumArea_content += "</table>";

        $("#tm_script_club_stadium_area_id").append(stadiumArea_content);

        $('#tm_script_input_fanbase').val(fanBase);
        $('#tm_script_input_current_capacity').val(currentCapacity);

        $('#tm_script_input_floodlights').val(floodlightsLevel);
        $('#tm_script_input_parking').val(parkingLevel);
        $('#tm_script_input_toilets').val(toiletsLevel);

        $('#tm_script_input_physio').val(physioLevel);
        $('#tm_script_input_pitch_draining').val(pitchDrainingLevel);
        $('#tm_script_input_pitch_cover').val(pitchCoverLevel);
        $('#tm_script_input_sprinklers').val(sprinklersLevel);
        $('#tm_script_input_heating').val(heatingLevel);
        $('#tm_script_input_medical_center').val(medicalCenterLevel);

        $('#tm_script_input_restaurant').val(restaurantLevel);
        $('#tm_script_input_merchandise_stand').val(merchandiseStandLevel);
        $('#tm_script_input_fast_food_place').val(fastFoodPlaceLevel);
        $('#tm_script_input_sausage_stand').val(sausageStandLevel);
        $('#tm_script_input_merchandise_store').val(merchandiseStoreLevel);

        $('#tm_script_input_youth_academy').val(youthAcademyLevel);
        $('#tm_script_input_training_grounds').val(trainingGroundsLevel);

        $('#tm_script_input_extra_home_match').val(extraHomeMatch);
        $('#tm_script_input_division').val(division);
        $('#tm_script_input_trade_player').val(tradePlayer);
        $('#tm_script_input_buy_star').val(buyStar);
        $('#tm_script_input_player_wage').val(playerWage);
        $('#tm_script_input_staff_wage').val(staffWage);
        $('#tm_script_input_building').val(building);
        $('#tm_script_input_adjust').val(adjust);

        $('#tm_script_span_average_attendance')[0].innerText = averageAttendance.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
        $('#tm_script_span_recommend_capacity')[0].innerText = recommendCapacity.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");

        $('#tm_script_span_ticket_income')[0].innerText = ticketIncome.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
        $('#tm_script_span_seat_maintain')[0].innerText = seatMantain.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
        $('#tm_script_span_ticket_profit')[0].innerText = ticketProfit.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");

        $('#tm_script_span_commerce_income')[0].innerText = commerceIncome.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
        $('#tm_script_span_commerce_maintain')[0].innerText = commerceMaintain.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
        $('#tm_script_span_commerce_profit')[0].innerText = commerceProfit.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");

        $('#tm_script_span_tv_money')[0].innerText = tvMoney.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
        $('#tm_script_span_sponsors')[0].innerText = sponsors.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
        $('#tm_script_span_other_maintain')[0].innerText = otherMaintain.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
        $('#tm_script_span_total_profit')[0].innerText = totalProfit.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");

        document.getElementById('tm_script_button_calculate').addEventListener('click', (e) => {
            calculate();
        });
    }

    function calculate() {
        let fanBaseCal = $('#tm_script_input_fanbase')[0].value.trim();
        let currentCapacityCal = $('#tm_script_input_current_capacity')[0].value.trim();

        let floodlightsLevelCal = $('#tm_script_input_floodlights')[0].value.trim();
        let parkingLevelCal = $('#tm_script_input_parking')[0].value.trim();
        let toiletsLevelCal = $('#tm_script_input_toilets')[0].value.trim();

        let physioLevelCal = $('#tm_script_input_physio')[0].value.trim();
        let pitchDrainingLevelCal = $('#tm_script_input_pitch_draining')[0].value.trim();
        let pitchCoverLevelCal = $('#tm_script_input_pitch_cover')[0].value.trim();
        let sprinklersLevelCal = $('#tm_script_input_sprinklers')[0].value.trim();
        let heatingLevelCal = $('#tm_script_input_heating')[0].value.trim();
        let medicalCenterLevelCal = $('#tm_script_input_medical_center')[0].value.trim();

        let restaurantLevelCal = $('#tm_script_input_restaurant')[0].value.trim();
        let merchandiseStandLevelCal = $('#tm_script_input_merchandise_stand')[0].value.trim();
        let fastFoodPlaceLevelCal = $('#tm_script_input_fast_food_place')[0].value.trim();
        let sausageStandLevelCal = $('#tm_script_input_sausage_stand')[0].value.trim();
        let merchandiseStoreLevelCal = $('#tm_script_input_merchandise_store')[0].value.trim();

        let youthAcademyLevelCal = $('#tm_script_input_youth_academy')[0].value.trim();
        let trainingGroundsLevelCal = $('#tm_script_input_training_grounds')[0].value.trim();

        let extraHomeMatchCal = $('#tm_script_input_extra_home_match')[0].value.trim();
        let divisionCal = $('#tm_script_input_division')[0].value.trim();
        let tradePlayerCal = $('#tm_script_input_trade_player')[0].value.trim();
        let buyStarCal = $('#tm_script_input_buy_star')[0].value.trim();
        let playerWageCal = $('#tm_script_input_player_wage')[0].value.trim();
        let staffWageCal = $('#tm_script_input_staff_wage')[0].value.trim();
        let buildingCal = $('#tm_script_input_building')[0].value.trim();
        let adjustCal = $('#tm_script_input_adjust')[0].value.trim();

        if (fanBaseCal == '' || currentCapacityCal == '' || floodlightsLevelCal == '' || parkingLevelCal == '' || toiletsLevelCal == '' || physioLevelCal == '' || pitchDrainingLevelCal == '' || pitchCoverLevelCal == '' || sprinklersLevelCal == '' || heatingLevelCal == '' || medicalCenterLevelCal == '' || restaurantLevelCal == '' || merchandiseStandLevelCal == '' || fastFoodPlaceLevelCal == '' || sausageStandLevelCal == '' || merchandiseStoreLevelCal == '' || youthAcademyLevelCal == '' || trainingGroundsLevelCal == '' || extraHomeMatchCal == '' || divisionCal == '' || tradePlayerCal == '' || buyStarCal == '' || playerWageCal == '' || staffWageCal == '' || buildingCal == '' || adjustCal == '') {
            alert('Enter value for all textboxs');
            return;
        }

        if (isNaN(fanBaseCal) || isNaN(currentCapacityCal) || isNaN(floodlightsLevelCal) || isNaN(parkingLevelCal) || isNaN(toiletsLevelCal) || isNaN(physioLevelCal) || isNaN(pitchDrainingLevelCal) || isNaN(pitchCoverLevelCal) || isNaN(sprinklersLevelCal) || isNaN(heatingLevelCal) || isNaN(medicalCenterLevelCal) || isNaN(restaurantLevelCal) || isNaN(merchandiseStandLevelCal) || isNaN(fastFoodPlaceLevelCal) || isNaN(sausageStandLevelCal) || isNaN(merchandiseStoreLevelCal) || isNaN(youthAcademyLevelCal) || isNaN(trainingGroundsLevelCal) || isNaN(extraHomeMatchCal) || isNaN(divisionCal) || isNaN(tradePlayerCal) || isNaN(buyStarCal) || isNaN(playerWageCal) || isNaN(staffWageCal) || isNaN(buildingCal) || isNaN(adjustCal)) {
            alert('Values must be a integer');
            return;
        }

        if (!(isInt(fanBaseCal) && isInt(currentCapacityCal) && isInt(floodlightsLevelCal) && isInt(parkingLevelCal) && isInt(toiletsLevelCal) && isInt(physioLevelCal) && isInt(pitchDrainingLevelCal) && isInt(pitchCoverLevelCal) && isInt(sprinklersLevelCal) && isInt(heatingLevelCal) && isInt(medicalCenterLevelCal) && isInt(restaurantLevelCal) && isInt(merchandiseStandLevelCal) && isInt(fastFoodPlaceLevelCal) && isInt(sausageStandLevelCal) && isInt(merchandiseStoreLevelCal) && isInt(youthAcademyLevelCal) && isInt(trainingGroundsLevelCal) && isInt(extraHomeMatchCal) && isInt(divisionCal) && isInt(tradePlayerCal) && isInt(buyStarCal) && isInt(playerWageCal) && isInt(staffWageCal) && isInt(buildingCal) && isInt(adjustCal))) {
            alert('Values must be a integer');
            return;
        }

        if (fanBaseCal < 0 || fanBaseCal > 100000) {
            alert('Fanbase value is between 0 - 100000');
            return;
        }
        if (currentCapacityCal < 0 || currentCapacityCal > 200000) {
            alert('Current stadium capacity value is between 0 - 200000');
            return;
        }
        if (floodlightsLevelCal < 0 || floodlightsLevelCal > 2) {
            alert('Floodlights level value is between 0 - 2');
            return;
        }
        if (parkingLevelCal < 0 || parkingLevelCal > 10) {
            alert('Parking level value is between 0 - 10');
            return;
        }
        if (toiletsLevelCal < 0 || toiletsLevelCal > 10) {
            alert('Toilets level value is between 0 - 10');
            return;
        }
        if (physioLevelCal < 0 || physioLevelCal > 10) {
            alert('Physio level value is between 0 - 10');
            return;
        }
        if (pitchDrainingLevelCal < 0 || pitchDrainingLevelCal > 1) {
            alert('Pitch draining level value is between 0 - 1');
            return;
        }
        if (pitchCoverLevelCal < 0 || pitchCoverLevelCal > 1) {
            alert('Pitch cover level value is between 0 - 1');
            return;
        }
        if (sprinklersLevelCal < 0 || sprinklersLevelCal > 1) {
            alert('Sprinklers level value is between 0 - 1');
            return;
        }
        if (heatingLevelCal < 0 || heatingLevelCal > 1) {
            alert('Heating level value is between 0 - 1');
            return;
        }
        if (medicalCenterLevelCal < 0 || medicalCenterLevelCal > 10) {
            alert('Medical center level value is between 0 - 10');
            return;
        }
        if (restaurantLevelCal < 0 || restaurantLevelCal > 10) {
            alert('Restaurant level value is between 0 - 10');
            return;
        }
        if (merchandiseStandLevelCal < 0 || merchandiseStandLevelCal > 10) {
            alert('Merchandise stand level value is between 0 - 10');
            return;
        }
        if (fastFoodPlaceLevelCal < 0 || fastFoodPlaceLevelCal > 10) {
            alert('Fast food place level value is between 0 - 10');
            return;
        }
        if (sausageStandLevelCal < 0 || sausageStandLevelCal > 10) {
            alert('Sausage stand level value is between 0 - 10');
            return;
        }
        if (merchandiseStoreLevelCal < 0 || merchandiseStoreLevelCal > 10) {
            alert('Merchandise store level value is between 0 - 10');
            return;
        }
        if (youthAcademyLevelCal < 0 || youthAcademyLevelCal > 10) {
            alert('Youth academy level value is between 0 - 10');
            return;
        }
        if (trainingGroundsLevelCal < 0 || trainingGroundsLevelCal > 10) {
            alert('Training grounds level value is between 0 - 10');
            return;
        }
        if (extraHomeMatchCal < 0 || extraHomeMatchCal > 50) {
            alert('Extra home match value is between 0 - 50');
            return;
        }
        if (divisionCal < 1 || divisionCal > 6) {
            alert('Division value is between 1 - 6');
            return;
        }
        if (playerWageCal < 0) {
            alert('Player wage value must be >= 0');
            return;
        }
        if (staffWageCal < 0) {
            alert('Staff wage value must be >= 0');
            return;
        }
        if (buildingCal < 0) {
            alert('Building value must be >= 0');
            return;
        }

        let averageAttendanceCal = calculateAverageAttendance(parkingLevelCal, toiletsLevelCal, floodlightsLevelCal, fanBaseCal, currentCapacityCal);
        let estimateAttendanceCal = calculateEstimateAttendance(parkingLevelCal, toiletsLevelCal, floodlightsLevelCal, fanBaseCal, currentCapacityCal);
        let recommendCapacityCal = calculateRecommendCapacity(parkingLevelCal, toiletsLevelCal, floodlightsLevelCal, fanBaseCal);

        let ticketIncomeCal = calculateTicketIncome(extraHomeMatchCal, averageAttendanceCal);
        let seatMantainCal = calculateSeatMaintain(currentCapacityCal);
        let ticketProfitCal = ticketIncomeCal - seatMantainCal;

        let commerceIncomeCal = calculateCommerceIncome(extraHomeMatchCal, averageAttendanceCal, restaurantLevelCal, merchandiseStandLevelCal, fastFoodPlaceLevelCal, sausageStandLevelCal, merchandiseStoreLevelCal);
        let commerceMaintainCal = calculateCommerceMaintain(restaurantLevelCal, merchandiseStandLevelCal, fastFoodPlaceLevelCal, sausageStandLevelCal, merchandiseStoreLevelCal);
        let commerceProfitCal = commerceIncomeCal - commerceMaintainCal;

        let tvMoneyCal = calculateTVMoney(divisionCal);
        let sponsorsCal = calculateSponsors(divisionCal);

        let otherMaintainCal = calculateOtherMaintain(physioLevelCal, pitchDrainingLevelCal, pitchCoverLevelCal, sprinklersLevelCal, heatingLevelCal, floodlightsLevelCal, parkingLevelCal, toiletsLevelCal, medicalCenterLevelCal, youthAcademyLevelCal, trainingGroundsLevelCal);
        let totalProfitCal = ticketProfitCal + commerceProfitCal + tvMoneyCal + sponsorsCal + Number(tradePlayerCal) - otherMaintainCal - playerWageCal * 12 - staffWageCal * 12 - buildingCal - buyStarCal + Number(adjustCal);

        $('#tm_script_span_average_attendance')[0].innerText = averageAttendanceCal.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
        $('#tm_script_span_recommend_capacity')[0].innerText = recommendCapacityCal.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");

        $('#tm_script_span_ticket_income')[0].innerText = ticketIncomeCal.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
        $('#tm_script_span_seat_maintain')[0].innerText = seatMantainCal.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
        $('#tm_script_span_ticket_profit')[0].innerText = ticketProfitCal.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");

        $('#tm_script_span_commerce_income')[0].innerText = commerceIncomeCal.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
        $('#tm_script_span_commerce_maintain')[0].innerText = commerceMaintainCal.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
        $('#tm_script_span_commerce_profit')[0].innerText = commerceProfitCal.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");

        $('#tm_script_span_tv_money')[0].innerText = tvMoneyCal.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
        $('#tm_script_span_sponsors')[0].innerText = sponsorsCal.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
        $('#tm_script_span_other_maintain')[0].innerText = otherMaintainCal.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
        $('#tm_script_span_total_profit')[0].innerText = totalProfitCal.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
    }

    function identifyFacilityLevel(facility) {
        let tooltip = facility.getAttribute('tooltip');
        let fromIndex = tooltip.search('等级:');
        let toIndex = tooltip.search(']</p>');
        let strLength = '等级:'.length + 1;
        return Number(tooltip.substr(fromIndex + strLength, toIndex - fromIndex - strLength).replace(/,/g, ''));
    }

    function calculateEstimateAttendance(parking, toilets, floodlights, fan, capacity) {
        let factor = (1 + parking / 100) * (1 + toilets / 100) * (1 + floodlights / 100) * (fan * 2.2);
        return Math.round((capacity < factor ? capacity : factor) * (1 - 0.05 / 100));
    }

    function calculateAverageAttendance(parking, toilets, floodlights, fan, capacity) {
        let factor = (1 + parking / 100) * (1 + toilets / 100) * (1 + floodlights / 100) * (fan * 2.244) * (1 - 7.5 / 100);
        return Math.round((capacity < factor ? capacity : factor) * (1 - 0.05 / 100));
    }

    function calculateRecommendCapacity(parking, toilets, floodlights, fan) {
        return Math.round((1 + parking / 100) * (1 + toilets / 100) * (1 + floodlights / 100) * (fan * 2.25));
    }

    function calculateOtherMaintain(physioLevel, pitchDrainingLevel, pitchCoverLevel, sprinklersLevel, heatingLevel, floodlightsLevel, parkingLevel, toiletsLevel, medicalCenterLevel, youthAcademyLevel, trainingGroundsLevel) {
        return 12 * (
            PHYSIO_MAINTAIN[physioLevel] +
            PITCH_DRAINING_MAINTAIN[pitchDrainingLevel] +
            PITCH_COVER_MAINTAIN[pitchCoverLevel] +
            SPRINKLERS_MAINTAIN[sprinklersLevel] +
            HEATING_MAINTAIN[heatingLevel] +
            FLOODLIGHTS_MAINTAIN[floodlightsLevel] +
            PARKING_MAINTAIN[parkingLevel] +
            TOILETS_MAINTAIN[toiletsLevel] +
            MEDICAL_CENTER_MAINTAIN[medicalCenterLevel] +
            YOUTH_ACADEMY_MAINTAIN[youthAcademyLevel] +
            TRAINING_GROUNDS_MAINTAIN[trainingGroundsLevel]);
    }

    function calculateCommerceIncome(extra = 0, attendance, restaurant, merchandiseStand, fastFoodPlace, sausageStand, merchandiseStore) {
        return Math.round(attendance * (
            restaurant * COMMERCE_PRICE.RESTAURANT * (COMMERCE_INCOME_FACTOR.RESTAURANT + CALCULATE_EXTRA_MATCH.RESTAURANT * extra) +
            merchandiseStand * COMMERCE_PRICE.MERCHANDISE_STAND * (COMMERCE_INCOME_FACTOR.MERCHANDISE_STAND + CALCULATE_EXTRA_MATCH.MERCHANDISE_STAND * extra) +
            fastFoodPlace * COMMERCE_PRICE.FAST_FOOD_PLACE * (COMMERCE_INCOME_FACTOR.FAST_FOOD_PLACE + CALCULATE_EXTRA_MATCH.FAST_FOOD_PLACE * extra) +
            sausageStand * COMMERCE_PRICE.SAUSAGE_STAND * (COMMERCE_INCOME_FACTOR.SAUSAGE_STAND + CALCULATE_EXTRA_MATCH.SAUSAGE_STAND * extra) +
            merchandiseStore * COMMERCE_PRICE.MERCHANDISE_STORE * (COMMERCE_INCOME_FACTOR.MERCHANDISE_STORE + CALCULATE_EXTRA_MATCH.MERCHANDISE_STORE * extra)));
    }

    function calculateCommerceMaintain(restaurant, merchandiseStand, fastFoodPlace, sausageStand, merchandiseStore) {
        return 12 * (
            restaurant * COMMERCE_MAINTAIN.RESTAURANT +
            merchandiseStand * COMMERCE_MAINTAIN.MERCHANDISE_STAND +
            fastFoodPlace * COMMERCE_MAINTAIN.FAST_FOOD_PLACE +
            sausageStand * COMMERCE_MAINTAIN.SAUSAGE_STAND +
            MERCHANDISE_STORE_MAINTAIN[merchandiseStore]);
    }

    function calculateTicketIncome(extra = 0, attendance) {
        return attendance * TICKET_PRICE * (17 + Number(extra)); //17 home match in league, extra is home match in cup, national cup...
    }

    function calculateSeatMaintain(seat) {
        return seat * SEAT_MAINTAIN * 12; //12 month
    }

    function calculateTVMoney(div) {
        return TV_MONEY[div] * 12;
    }

    function calculateSponsors(div) {
        return Math.round(SPONSORS[div] * 12 * 7 / 10);
    }

    function isInt(n) {
        return n % 1 === 0;
    }
})();